export interface Protocol {
    version: Version;
    domains: Domain[];
}
export interface Version {
    major: string;
    minor: string;
}
export type VersionStatus = {
    experimental?: boolean;
    deprecated?: boolean;
};
export type Domain = {
    domain: string;
    description?: string;
    /**
     * 是否废弃，可选。
     * 如果没有该 key，则表示未废弃
     */
    deprecated?: boolean;
    dependencies?: string[];
    /**
     * 命名空间内的具名类型
     */
    types?: NamedType[];
    commands?: Command[];
    events?: Event[];
} & VersionStatus;

export interface Command extends Event {
    /**
     * 如果缺省则表示非实验性命令
     */
    experimental?: boolean;
    // 文档中返回类型必须给出返回值的名称，因此是具名类型。
    // json 文件中表现出来的是数组，但文档中实际为对象。
    returns?: Property[];
}

// 事件类似于一种反向命令，（由服务端发送给客户端）
export type Event = {
    name: string;
    description: string;
    parameters?: Parameter[];
} & VersionStatus;

export type Parameter = Property;

/**
 * 对象类型的属性
 */
export type Property =
    & {
        name: string;
        description: string;
        optional?: boolean;
        // information about type
    }
    & AnonymousType
    & VersionStatus;

export interface ObjectType {
    type: 'object';
    properties?: Property[];
}
export interface ArrayType {
    type: 'array';
    /** Maps to a typed array e.g string[] */
    items: AnonymousType;
}
export interface RefType {
    $ref: string;
}
export interface PrimitiveType {
    type: 'number' | 'integer' | 'boolean' | 'any' | 'string';
}
export type EnumType = {
    enum: string[];
} & PrimitiveType;
export type AnonymousType =
    | PrimitiveType
    | EnumType
    | ObjectType
    | ArrayType
    | RefType;
export type NamedType =
    & {
        // name information
        id: string;
        description: string;
    }
    & AnonymousType
    & VersionStatus;
